import re

from constants.consts import USER_AGENT_GITEE, USER_AGENT_GITCODE
from logger import logger
from sub_events.base_event import BaseEvent, CHECK_RESULT_FAIL

LOGGER = logger.CustomLogger()


class CheckCommitMsg(BaseEvent):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.event_name_zh: str = "提交信息检查"
        self.event_name_en: str = "Commit Message Check"

        self.xts_tdd_expect_result = ["pass", "fail", "不涉及"]
        self.compatibility_expect_result = ["是", "否", "不涉及"]
        self.review_comments_result = ["是", "否", "yes", "no"]
        self.all_self_check_items = {
            "Feature or Bugfix",
            "是否涉及非兼容变更/Whether it involves incompatible changes",
            "TDD自验结果/TDD Self-Verification Results",
            "XTS自验结果/XTS Self-Verification Results",
            "检视意见是否都已闭环/Have all review comments been resolved",
            "是否已执行L0用例"
        }
        self.blacklist_words = {
            "华为用词": r"强基|黄区|蓝区|DTS|鸿蒙|EMUI|华为|合作|单(?:框架|框)|双(?:框架|框)|工号|慧眼",
            "AR/IR/SR编号": r"(?:IR|AR|SR)\d{14}",
            "工号": r"\b(?:[a-z]\d{8}|\d{8}|[a-z]\d{6}|\d{6}|[a-z]wx\d{7}|wx\d{7})\b",
        }

        self.format_check = True
        self.word_check = True

    def remove_images_from_markdown(self, content):
        """移除Markdown内容中的所有图片标记"""
        # 匹配标准Markdown图片语法 ![alt](url) 和可能的变体
        pattern = r'!\[.*?\]\(.*?\)'
        return re.sub(pattern, '', content)

    def check_text_for_patterns(self, text):
        """
        检查文本中是否包含匹配指定模式的字符串
        返回包含匹配结果的字典
        """
        results = {}

        for pattern_name, pattern in self.blacklist_words.items():
            # 使用IGNORECASE标志使匹配不区分大小写
            matches = re.findall(pattern, text, re.IGNORECASE)
            if matches:
                results[pattern_name] = matches

        return results

    def validate_markdown_checkboxes(self, commit_msg: str):
        section_pattern = r'^### (.+?)\n((?:- \[[ x]\] .+\n?)+)'

        results = {}
        failed_result = []
        failed_suggestion = "请确保该自检项有且只有一个复选框被正确勾选。\n\n" + \
                            "Please ensure that exactly one checkbox is selected for this self-check item."
        for match in re.finditer(section_pattern, commit_msg, re.MULTILINE):
            section_name = match.group(1).strip()
            checkbox_lines = match.group(2).strip().split('\n')

            checked_count = 0
            for line in checkbox_lines:
                if line.strip().startswith('- [x]'):
                    checked_count += 1

            results[section_name] = checked_count == 1
            if checked_count != 1:
                failed_result.append({
                    "section_name": section_name,
                    "result": CHECK_RESULT_FAIL,
                    "details": failed_suggestion
                })
        if failed_result:
            self.comment = self.generate_html_table(failed_result) + "\n"
            self.format_check = False
        if set(results.keys()) != self.all_self_check_items:
            self.format_check = False
            missing_item = self.all_self_check_items - set(results.keys())
            self.comment += "提交信息中缺少以下自检项：\n\nThe commit message is missing the following self-check items:\n\n"
            self.comment += str(list(missing_item))

    def check_msg_format(self, commit_msg):
        self.validate_markdown_checkboxes(commit_msg)

    def check_words_legal(self, commit_msg):
        matches = self.check_text_for_patterns(commit_msg)
        match_result = ""
        if matches:
            self.word_check = False
            match_result = "在提交信息中发现了以下匹配：\n"

            for pattern_type, found_matches in matches.items():
                match_result += f"\n{pattern_type} 匹配项 ({len(found_matches)}个):"
                for i, match in enumerate(found_matches, 1):
                    match_result += f"\n  · {match}"
        if not self.word_check:
            LOGGER.error(f"{self.hook.pr_number}] 用语不规范：{match_result}")
            self.comment = "请注意检查提交信息中的规范用语，如有疑问请联系\nliyujie: @liyujie43\nlusong: @royce-ls"

    def execute(self):
        """
        检查提交信息是否合规
        """
        commit_msg = ""
        if self.hook.user_agent == USER_AGENT_GITEE:
            commit_msg = self.hook.commit_msg
        if self.hook.user_agent == USER_AGENT_GITCODE:
            pr_info = self.git_client.get_pr_info(self.hook.pr_number, token=self.get_admin_token())
            commit_msg = pr_info.get("body")
        if not commit_msg:
            self.failed = True
            self.format_check = False
        else:
            commit_msg = self.remove_images_from_markdown(commit_msg)
            self.check_msg_format(commit_msg)
            self.check_words_legal(commit_msg)
            self.failed = not (self.format_check and self.word_check)
        if self.failed:
            self.comment = ("若当前提交信息与模板不同，请查看本代码库master分支的.gitcode目录下的PULL_REQUEST_TEMPLATE.md文件，"
                            "点击\"源码\"旁边的\"复制\"，然后编辑本次提交信息，粘贴复制的模板，再进行相应的修改。\n\n"
                            "If the current commit message differs from the template, please refer to the "
                            "PULL_REQUEST_TEMPLATE.md file in the .gitcode directory of this repository's master "
                            "branch. Click 'Copy' next to 'Source Code', then edit your commit message, paste the "
                            "copied template, and make the necessary modifications.\n") + self.comment
